#include "rtp/ReceiverReport.h"

namespace Rtp {
    namespace Rtcp {
        ReceiverReport* ReceiverReport::Parse(const uint8_t *data, size_t len) {

            auto *header = const_cast<Header*>(reinterpret_cast<const Header*>(data));

            if (len < HeaderSize) {
                return nullptr;
            }

            return new ReceiverReport(header);
        }

        void ReceiverReport::Dump() const {}

        size_t ReceiverReport::Serialize(uint8_t* buffer) {
            std::memcpy(buffer, this->header, HeaderSize);

            return HeaderSize;
        }

        size_t ReceiverReportPacket::MaxReportsPerPacket = 31;

        ReceiverReportPacket* ReceiverReportPacket::Parse(const uint8_t* data, size_t len, size_t offset) {
            auto *header = const_cast<CommonHeader *>(reinterpret_cast<const CommonHeader*>(data));

            if (len < Packet::CommonHeaderSize + 4u) {
                return nullptr;
            }

            std::unique_ptr<ReceiverReportPacket> packet(new ReceiverReportPacket(header));

            const uint32_t ssrc = Utils::Byte::Get4Bytes(reinterpret_cast<uint8_t*>(header), Packet::CommonHeaderSize);

            packet->SetSsrc(ssrc);

            if (offset == 0) {
                offset = Packet::CommonHeaderSize + 4u;
            }

            uint8_t count = header->count;
            while((count-- != 0u) && (len > offset)) {
                ReceiverReport *report = ReceiverReport::Parse(data + offset, len - offset);

                if (report != nullptr) {
                    packet->AddReport(report);
                    offset += report->GetSize();
                } else {
                    return packet.release();
                }
            }

            return packet.release();
        }

        void ReceiverReportPacket::Dump() const {
            for (auto *report : this->reports) {
                report->Dump();
            }
        }
    }
}